"""
FastAPI证件照处理应用

这是一个基于FastAPI的证件照处理服务，提供以下功能：
1. 证件照生成（标准照、高清照、透明背景照、排版照）
2. 社交媒体模板生成
3. 文件自动存储和管理
4. 定时清理过期文件
5. RESTful API接口

启动方式：
    uvicorn main:app --host 0.0.0.0 --port 8000 --reload

API文档：
    访问 http://localhost:8000/docs 查看交互式API文档
    访问 http://localhost:8000/redoc 查看ReDoc文档
"""

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from pathlib import Path
import logging
import sys

# 配置日志
logs_dir = Path("logs")
logs_dir.mkdir(exist_ok=True)
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler(str(logs_dir / "app.log"))
    ]
)
logger = logging.getLogger(__name__)

# 导入路由
from routers.id_photo_router import router as id_photo_router
from routers.user_router import router as user_router
from routers.beauty_router import router as beauty_router
from config import STORAGE_CONFIG

# 创建FastAPI应用
app = FastAPI(
    title="证件照处理服务",
    description="基于FastAPI的证件照处理服务，支持多种尺寸和背景颜色的证件照生成",
    version="1.0.0",
    docs_url="/docs",
    redoc_url="/redoc"
)
openid_dir = Path("openid")
openid_dir.mkdir(exist_ok=True)
app.mount("/openid", StaticFiles(directory=str(openid_dir)), name="openid")

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 在生产环境中应该配置具体的域名
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 微信小程序请求验证中间件
from fastapi import Request
from fastapi.responses import JSONResponse

@app.middleware("http")
async def wechat_mini_program_middleware(request: Request, call_next):
    """
    验证请求是否来自微信小程序
    微信小程序的User-Agent包含'miniProgram'关键字
    """
    # 跳过健康检查和根路径
    if request.url.path in ["/health", "/", "/docs", "/redoc", "/openapi.json"]:
        response = await call_next(request)
        return response
    
    # 获取User-Agent
    user_agent = request.headers.get("User-Agent", "")
    
    # 检查是否来自微信小程序
    if "miniProgram" not in user_agent and "MicroMessenger" not in user_agent:
        return JSONResponse(
            status_code=403,
            content={
                "success": False,
                "message": "拒绝访问：只允许微信小程序请求",
                "status_code": 403
            }
        )
    
    response = await call_next(request)
    return response

# 挂载静态文件目录
static_dir = Path("static")
static_dir.mkdir(exist_ok=True)

# 挂载文件存储目录到/static路径
storage_dir = STORAGE_CONFIG["base_dir"]
if storage_dir.exists():
    app.mount("/static", StaticFiles(directory=str(storage_dir)), name="openid_files")
    app.mount("/files", StaticFiles(directory=str(storage_dir)), name="files")


@app.on_event("startup")
async def startup_event():
    """应用启动时的初始化工作"""
    logger.info("=" * 50)
    logger.info("证件照处理服务启动中...")
    logger.info("=" * 50)

    # 检查必要的目录
    from config import create_directories
    create_directories()

    # 检查文件存储目录
    if not storage_dir.exists():
        storage_dir.mkdir(parents=True, exist_ok=True)
        logger.info(f"创建文件存储目录: {storage_dir}")

    logger.info("应用启动完成")


@app.on_event("shutdown")
async def shutdown_event():
    """应用关闭时的清理工作"""
    logger.info("应用正在关闭...")
    # 这里可以添加清理代码，如关闭数据库连接等
    logger.info("应用已关闭")


# 健康检查端点
@app.get("/health")
async def health_check():
    """健康检查接口"""
    return {
        "status": "healthy",
        "service": "证件照处理服务",
        "version": "1.0.0"
    }


# 根路径
@app.get("/")
async def root():
    """根路径接口"""
    return {
        "message": "欢迎使用证件照处理服务",
        "version": "1.0.0",
        "docs": "/docs",
        "api_prefix": "/api/idphoto"
    }


# 注册路由
app.include_router(id_photo_router)
app.include_router(user_router)
app.include_router(beauty_router)


# 全局异常处理
from fastapi.responses import JSONResponse

@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
    """HTTP异常处理"""
    logger.error(f"HTTP异常: {exc.status_code} - {exc.detail}")
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "success": False,
            "message": str(exc.detail),
            "status_code": exc.status_code
        }
    )


@app.exception_handler(Exception)
async def general_exception_handler(request, exc):
    """通用异常处理"""
    logger.error(f"未处理的异常: {exc}", exc_info=True)
    return JSONResponse(
        status_code=500,
        content={
            "success": False,
            "message": "服务器内部错误",
            "status_code": 500
        }
    )


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
    )